package com.easycode.devtool.util;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.URL;
import java.net.URLConnection;
import java.net.UnknownHostException;
import java.util.StringTokenizer;

/**
 * Created by Soholife on 2015/6/4.
 *
 * IP相关功能集合类
 */
final public  class  IPUtils
{
    /**
     * 获取用户真实IP地址，不使用request.getRemoteAddr();的原因是有可能用户使用了代理软件方式避免真实IP地址,
     *
     * 可是，如果通过了多级反向代理的话，X-Forwarded-For的值并不止一个，而是一串IP值，究竟哪个才是真正的用户端的真实IP呢？
     * 答案是取X-Forwarded-For中第一个非unknown的有效IP字符串。
     *
     * 如：X-Forwarded-For：192.168.1.110, 192.168.1.120, 192.168.1.130,
     * 192.168.1.100
     *
     * 用户真实IP为： 192.168.1.110
     *
     * @param request
     * @return
     */
    public static String getIpAddress(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

    /**
     * 获取用户原始IP地址信息
     *
     * 因为我们有可能使用的是CDN，那么这里将获取CDN节点IP
     * 这里一个是网宿的，一个是蓝讯的，如果有其它CDN的，则重新修改本方法即可
     */
    public static String getIp(HttpServletRequest request)
    {
        String ip = "";
        try
        {
            ip = request.getHeader("Cdn-Src-Ip");

            if(ip == "" || ip == null)
            {
                ip = request.getHeader("X-Forwarded-For");
            }

            //不是CDN的节点，那么获取原始IP
            if(ip == "" || ip == null)
            {
                ip= request.getRemoteAddr();
            }
        }
        catch (Exception e){;       }

        return ip;
    }


    /**
     * IP地址转换成长整数数据
     * @param ip
     * @return 数字IP
     */
    public static long IpToInt(String ip)
    {
        long ip_Int = 0;
        try
        {
            StringTokenizer stringTokenizer = new StringTokenizer(ip,".");
            while (stringTokenizer.hasMoreElements())
            {
               String p1 = String.valueOf(stringTokenizer.nextElement());
                System.out.println(p1);
            }
            String[] ipArr = ip.split("\\.");
            if (ipArr.length == 3)
                ip = ip + ".0";
            ipArr = ip.split("\\.");

            long p1 = Long.parseLong(ipArr[0]) * 256 * 256 * 256;
            long p2 = Long.parseLong(ipArr[1]) * 256 * 256;
            long p3 = Long.parseLong(ipArr[2]) * 256;
            long p4 = Long.parseLong(ipArr[3]);
            ip_Int = p1 + p2 + p3 + p4;
        }
        catch(Exception e)
        {
            String sError = "IP"+ip+"发生错误" + e.getMessage() + "<BR>" + e.getStackTrace();
        }
        return ip_Int;
    }


    /**
     * 长整数IP地址，转换成IP记录
     * @param ip_Int
     * @return IP值
     */
    public static String IntToIP(long ip_Int)
    {
        String ip = "";
        try
        {
            long seg1 = (ip_Int & 0xff000000) >> 24;
            if (seg1 < 0)
                seg1 += 0x100;
            long seg2 = (ip_Int & 0x00ff0000) >> 16;
            if (seg2 < 0)
                seg2 += 0x100;
            long seg3 = (ip_Int & 0x0000ff00) >> 8;
            if (seg3 < 0)
                seg3 += 0x100;
            long seg4 = (ip_Int & 0x000000ff);
            if (seg4 < 0)
                seg4 += 0x100;
            ip =  String.valueOf(seg1) + "." +String.valueOf(seg2) + "." + String.valueOf(seg3) + "." +String.valueOf(seg4);
        }
        catch(Exception e) { ;}

        return ip;
    }

    /**
     * 通过IP地址，获取所在地区 (这个方法未进测试，而且由于是通过外网的API接口访问的，性能慢，高并发操作任务重，不使用该方法)
     * @param strIP ip地址信息
     * @return
     */
    public static String getIPArea_Slow(String strIP)
    {
        String s = "";
        try
        {
            //String strIP = "0.0.0.0";
            URL url = new URL( "http://ip.qq.com/cgi-bin/searchip?searchip1=" + strIP);
            URLConnection conn = url.openConnection();
            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "GBK"));
            String line = null;
            StringBuffer result = new StringBuffer(32);
            while((line = reader.readLine()) != null)
            {
                result.append(line);
            }
            reader.close();
            conn = null;
            url = null;

            //strIP = result.substring(result.indexOf( "该IP所在地为：" ));
            //strIP = strIP.substring(strIP.indexOf( "：") + 1);
            //String province = strIP.substring(6, strIP.indexOf("省"));
            //String city = strIP.substring(strIP.indexOf("省") + 1, strIP.indexOf("市"));

            strIP = result.substring(result.indexOf( "该IP所在地为：" ));
            s = strIP.substring(strIP.indexOf( "：") + 1);
            result = null;
        }
        catch( IOException e)
        {
            ;
        }

        return s;
    }


    public static String getLocalIP()
    {
        try {
            String webServerIP = InetAddress.getLocalHost().getHostAddress();
            return  webServerIP;
        } catch (UnknownHostException e) {
//            e.printStackTrace();
        }
        return "";
    }
    public static String getLocalHostName()
    {
        try {
            String canonicalHostName = InetAddress.getLocalHost().getHostName();
            return  canonicalHostName;
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        return "";
    }

//    public static void main(String[] args)
//    {
////        String ip = "220.243.139.186";
////        long ip_long = IPUtils.IpToInt(ip);
////        System.out.println(ip_long);
//        System.out.println(getLocalIP());
//        System.out.println(getLocalHostName());
//    }
}
